package com.heima.comment.service.impl;

import com.heima.comment.entity.ApComment;
import com.heima.comment.entity.ApCommentLike;
import com.heima.comment.service.ApCommentService;
import com.heima.comment.vo.CommentVo;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.constants.message.HotArticleConstants;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.common.exception.LeadException;
import com.heima.common.threadlocal.UserThreadLocalUtils;
import com.heima.common.util.BeanHelper;
import com.heima.common.util.JsonUtils;
import com.heima.model.article.msg.ArticleBehaviorMsg;
import com.heima.model.comment.dtos.CommentDto;
import com.heima.model.comment.dtos.CommentLikeDto;
import com.heima.model.comment.dtos.CommentSaveDto;
import com.heima.model.user.dtos.UserInfoDto;
import com.heima.user.client.UserFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ApCommentServiceImpl implements ApCommentService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private UserFeign userFeign;

    @Autowired
    private GreenTextScan greenTextScan;

    @Autowired
    private KafkaTemplate kafkaTemplate;


    @Override
    public void saveComment(CommentSaveDto dto) {
        //获取评论内容，进行文本反垃圾操作
        try {
            Map<String, String> map = greenTextScan.greenTextScan(dto.getContent());
            if(!"pass".equals(map.get("suggestion"))){
                throw new LeadException(AppHttpCodeEnum.TEXT_ILLEGAL);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        //1、获取用户id，判断用户登录状态
        Integer userId = UserThreadLocalUtils.getUserId();
        if(userId==null || userId==0){
            throw new LeadException(AppHttpCodeEnum.NEED_LOGIN);
        }
        //基于用户id查询用户信息
        UserInfoDto userInfoDto = userFeign.findUserById(userId);
        if(userInfoDto==null){
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST,"登录用户信息不存在");
        }
        //2、保存评论数据
        ApComment apComment = new ApComment();
        apComment.setAuthorId(userId);
        apComment.setAuthorName(userInfoDto.getName());//登录用户名称
        apComment.setContent(dto.getContent());
        apComment.setEntryId(dto.getArticleId());
        apComment.setFlag(0);//0 普通评论
        apComment.setImage(userInfoDto.getImage());
        apComment.setLikes(0);//点赞数
        apComment.setType(0);//0 文章
        apComment.setReply(0);
        apComment.setCreatedTime(new Date());
        apComment.setUpdatedTime(new Date());
        mongoTemplate.insert(apComment);
        //文章评论后，生成评论行为消息
        ArticleBehaviorMsg articleBehaviorMsg = new ArticleBehaviorMsg(
                dto.getArticleId(),
                1,
                ArticleBehaviorMsg.ArticleBehaviorType.COMMENT);
        kafkaTemplate.send(HotArticleConstants.HOT_ARTICLE_SCORE_STREAM_TOPIC, JsonUtils.toString(articleBehaviorMsg));
    }

    @Override
    public List<CommentVo> loadComment(CommentDto dto) {
        //1、获取用户id
        Integer userId = UserThreadLocalUtils.getUserId();

        //2、获取文章id，查询文章的评论列表
        Long articleId = dto.getArticleId();
       //构建查询条件
        Query query = Query.query(Criteria.where("entryId").is(articleId));
        //点赞数量条件设置
        if(dto.getMinLikes()!=null){
            query.addCriteria(Criteria.where("likes").lt(dto.getMinLikes()));
        }
        //设置排序条件
        query.with(Sort.by(Sort.Direction.DESC,"likes"));
        //设置分页条件
        Long page = dto.getPage()-1;
        Long size = dto.getSize();
        Pageable pageable = PageRequest.of(Integer.parseInt(page.toString()),Integer.parseInt(size.toString()));
        query.with(pageable);
        //执行查询
        List<ApComment> apCommentList = mongoTemplate.find(query, ApComment.class);
        if(CollectionUtils.isEmpty(apCommentList)){
            return null;
        }
        List<CommentVo> commentVoList = BeanHelper.copyWithCollection(apCommentList, CommentVo.class);
        //判断当前用户是否登录
        if(userId==null || userId==0){
            //直接返回评论列表
            return commentVoList;
        }
        //获取当前文章评论列表中所有id值
        List<String> commentIds = apCommentList.stream().map(ApComment::getId).collect(Collectors.toList());

        //如果用户登录了，需要查询当前登录用户是否对某些评论进行了点赞操作，需要记录点赞评论数据
        Query query1 = Query.query(Criteria.where("authorId").is(userId).
                and("commentId").in(commentIds).
                and("operation").is(0));
        List<ApCommentLike> commentLikeList = mongoTemplate.find(query1, ApCommentLike.class);
        if(!CollectionUtils.isEmpty(commentLikeList)){
            //判断评论列表中，那个评论被点赞过
            List<String> likeCommentIds = commentLikeList.stream().map(ApCommentLike::getCommentId).collect(Collectors.toList());
            commentVoList.stream().forEach(commentVo -> {
                if(likeCommentIds.contains(commentVo.getId())){
                    //                        评论id一致，说明用户给这个品论点赞过，设置为0
                    commentVo.setOperation(0);
                }
            });
        }
        return commentVoList;
    }

    @Override
    public void likeComment(CommentLikeDto dto) {
        //获取用户id
        Integer userId = UserThreadLocalUtils.getUserId();
        if(userId==null || userId==0){
            throw new LeadException(AppHttpCodeEnum.NEED_LOGIN);
        }
        //获取评论id查询评论数据
        String commentId = dto.getCommentId();
        //查询评论数据
        ApComment comment = mongoTemplate.findById(commentId, ApComment.class);
        if(comment==null){
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST,"评论数据不存在");
        }
        //查询当前用户是否对该评论是否点赞过
        Query query = Query.query(Criteria.where("authorId").is(userId).
                and("commentId").is(commentId));
        ApCommentLike apCommentLike = mongoTemplate.findOne(query, ApCommentLike.class);
        //如果未点赞过，此次操作是点赞行为，保存点赞操作
        if(apCommentLike==null && dto.getOperation()==0){
            //保存点赞操作
            apCommentLike = new ApCommentLike();
            apCommentLike.setAuthorId(userId);
            apCommentLike.setCommentId(commentId);
            apCommentLike.setOperation(dto.getOperation());
            mongoTemplate.insert(apCommentLike);
            //更新评论点赞次数
            Query query1 = Query.query(Criteria.where("_id").is(commentId));
            Update update = new Update();
            update.inc("likes");
            mongoTemplate.updateFirst(query1,update,ApComment.class);
        }else if(apCommentLike !=null && dto.getOperation()!=apCommentLike.getOperation()){
            //如果点赞过，更新点赞操作
            apCommentLike.setOperation(dto.getOperation());
            mongoTemplate.save(apCommentLike);

            //更新评论点赞次数
            Query query1 = Query.query(Criteria.where("_id").is(commentId));
            Update update = new Update();

            int inc = dto.getOperation() == 0 ? 1 : -1;
            //如果点赞数量已经是0，即便是取消点赞也不能再减一
            if(inc==-1 && comment.getLikes()<1){
                return ;
            }
            update.inc("likes",inc);
            mongoTemplate.updateFirst(query1,update,ApComment.class);
        }

    }
}
